<template>
  <div class="singer-wrapper">
    <div class="singer" v-show="singersList.length>0" ref="singer">
      <scroll
        class="singer-content"
        :data="this.singersList"
        ref="Listview"
        :listen-scroll="listenScroll"
        @scroll="scroll"
        :probeType="probeType"
      >
        <ul class="listview">
          <li
            v-for="(item,index) in this.singersList"
            :key="index"
            class="list-group"
            ref="listGroup"
          >
            <h2 class="list-group-title">{{item.title}}</h2>
            <ul>
              <li
                v-for="(tag,j) in item.items"
                :key="j"
                class="list-group-item"
                @click="Todetail(tag)"
              >
                <div class="avatar" v-lazy:background-image="tag.avatar"></div>
                <span class="name">{{tag.name}}</span>
              </li>
            </ul>
          </li>
        </ul>
        <div
          class="list-shortcut"
          @touchstart="onShortcutTouchStart"
          @touchmove.stop.prevent="onShortcutTouchMove"
        >
          <ul>
            <li
              v-for="(item, index) in shortcutList"
              class="item"
              :key="index"
              :class="{'current':currentIndex===index}"
              :data-index="index"
            >{{item}}</li>
          </ul>
        </div>
        <div class="list-fixed" ref="fixed" v-show="fixedTitle">
          <div class="fixed-title">{{fixedTitle}}</div>
        </div>
      </scroll>
    </div>
    <van-loading v-show="!singersList.length" type="circular" color="#fff" vertical>加载歌手列表...</van-loading>
    <!-- 歌手详情动态路由: -->
    <router-view></router-view>
  </div>
</template>

<script>
import { getHotSinger } from "@/request/api.js";
import Scroll from "@/base/scroll/scroll";
import { PYName } from "@/utils/pinyin.js";
import storage from "@/utils/storage.js";
import { getData } from "@/utils/dom.js";
import { mapMutations } from "vuex";
import { playListMixin } from "@/common/mixin.js";

const HOT_NAME = "热门";
const HOT_SINGER_LEN = 10;
// 定义每个字母的高度
const ANCHOR_HEIGHT = 18;
// 定义标题高度
const TITLE_HEIGHT = 30;
export default {
  mixins: [playListMixin],
  data() {
    return {
      singersList: [],
      // bs滚动的距离
      scrollY: -1,
      // 当前高亮的
      currentIndex: 0,
      diff: -1
    };
  },
  components: {
    Scroll
  },
  created() {
    // 获取歌手列表
    var singerList = storage.get("singerList");
    if (singerList) {
      console.log("从localStorage获取数据");
      this.singersList = singerList;
    } else {
      this._getSingerList();
    }
    // 因为不用观测touch的变化，所以不用把touch放入data中
    this.touch = {};
    this.listenScroll = true;
    this.listHeight = [];
    this.probeType = 3;
  },
  watch: {
    singersList() {
      setTimeout(() => {
        this._coutHeight();
      }, 20);
    },
    scrollY(newY) {
      const listHeight = this.listHeight;
      // 当滚动到顶部，newY>0
      if (newY > 0) {
        this.currentIndex = 0;
        return;
      }
      // 在中间部分滚动
      for (let i = 0; i < listHeight.length - 1; i++) {
        let height1 = listHeight[i];
        let height2 = listHeight[i + 1];
        if (-newY >= height1 && -newY < height2) {
          this.currentIndex = i;
          this.diff = height2 + newY;
          return;
        }
      }
      // 当滚动到底部，且-newY大于最后一个元素的上限
      this.currentIndex = listHeight.length - 2;
    },
    diff(newVal) {
      let fixedTop =
        newVal > 0 && newVal < TITLE_HEIGHT ? newVal - TITLE_HEIGHT : 0;
      if (this.fixedTop === fixedTop) {
        return;
      }
      this.fixedTop = fixedTop;
      this.$refs.fixed.style.transform = `translate3d(0,${fixedTop}px,0)`;
    }
  },
  methods: {
    handlePlayList(playlist) {
      const bottom = playlist.length > 0 ? "60px" : "";
      this.$refs.singer.style.bottom = bottom;
      this.$refs.Listview.refresh();
    },
    async _getSingerList() {
      const singerData = await getHotSinger({ limit: 50 });
      this.singersList = this._normalizeSinger(singerData.artists);
      storage.set("singerList", this.singersList);
    },

    _normalizeSinger(list) {
      let map = {
        hot: {
          title: HOT_NAME,
          items: []
        }
      };
      list.forEach((item, index) => {
        if (index < HOT_SINGER_LEN) {
          map.hot.items.push({
            id: item.id,
            name: item.name,
            avatar: item.picUrl + "?param=300y300"
          });
        }
        const key = PYName(item.name);
        if (!map[key]) {
          map[key] = {
            title: key,
            items: []
          };
        }
        map[key].items.push({
          id: item.id,
          name: item.name,
          avatar: item.picUrl + "?param=300y300"
        });
      });
      // 得到有序列表，重新处理map
      let hot = [];
      let ret = [];
      for (let key in map) {
        let val = map[key];
        if (val.title.match(/[a-zA-Z]/)) {
          ret.push(val);
        } else if (val.title === HOT_NAME) {
          hot.push(val);
        }
      }
      ret.sort((a, b) => {
        return a.title.charCodeAt(0) - b.title.charCodeAt(0);
      });
      return hot.concat(ret);
    },
    // 点击锚点跳转:
    onShortcutTouchStart(e) {
      // 获取锚点索引
      let anchorIndex = getData(e.target, "index");
      // 获取第一次Touch的手指位置
      let firstTouch = e.touches[0];
      this.touch.y1 = firstTouch.pageY;
      this.touch.anchorIndex = anchorIndex;
      this._scrollTo(anchorIndex);
    },
    // 移动锚点跳转：
    onShortcutTouchMove(e) {
      let firstTouch = e.touches[0];
      this.touch.y2 = firstTouch.pageY;
      // 获取在y轴上的偏移;
      let delta = ((this.touch.y2 - this.touch.y1) / ANCHOR_HEIGHT) | 0;
      let anchorIndex = parseInt(this.touch.anchorIndex) + delta;
      this._scrollTo(anchorIndex);
    },
    scroll(pos) {
      // 获取betterscroll滚动的y轴距离
      this.scrollY = pos.y;
    },
    _coutHeight() {
      this.listHeight = [];
      const list = this.$refs.listGroup;
      let height = 0;
      this.listHeight.push(height);
      for (let i = 0; i < list.length; i++) {
        let item = list[i];
        height += item.clientHeight;
        this.listHeight.push(height);
      }
    },
    _scrollTo(index) {
      if (!index && index !== 0) {
        return;
      }
      if (index < 0) {
        index = 0;
      } else if (index > this.listHeight.length - 2) {
        index = this.listHeight.length - 2;
      }
      this.scrollY = -this.listHeight[index];
      this.$refs.Listview.scrollToElement(this.$refs.listGroup[index], 0);
    },
    Todetail(item) {
      // console.log(item);
      this.$router.push({
        path: `/singer/${item.id}`
      });
      // 实际调用了this.$store.commit('setSinger',item)....
      this.setSinger(item);
    },
    ...mapMutations({
      setSinger: "SET_SINGER"
    })
  },
  computed: {
    shortcutList() {
      return this.singersList.map(group => {
        return group.title.substr(0, 1);
      });
    },
    fixedTitle() {
      if (this.scrollY > 0) {
        return "";
      }
      return this.singersList[this.currentIndex]
        ? this.singersList[this.currentIndex].title
        : "";
    }
  }
};
</script>

<style scoped lang="less">
.singer {
  position: fixed;
  top: 88px;
  bottom: 0;
  width: 100%;
}
.singer-content {
  height: 100%;
  overflow: hidden;
  position: relative;
}
.listview {
  background: @color-background;
  overflow: hidden;
  .list-group {
    padding-bottom: 30px;
    .list-group-title {
      height: 30px;
      line-height: 30px;
      padding-left: 20px;
      font-size: @font-size-small;
      color: @color-text-l;
      background: @color-highlight-background;
    }
    .list-group-item {
      display: flex;
      align-items: center;
      padding: 20px 0 0 30px;
      .avatar {
        width: 50px;
        height: 50px;
        border-radius: 50%;
        .bz(cover);
      }
      .name {
        margin-left: 20px;
        color: @color-text-l;
        font-size: 14px;
      }
    }
  }
}
.list-shortcut {
  position: absolute;
  z-index: 30;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 20px;
  padding: 20px 0;
  border-radius: 10px;
  text-align: center;
  background: @color-background-d;
  font-family: Helvetica;
  .item {
    padding: 3px;
    line-height: 1;
    color: @color-text-l;
    font-size: @font-size-small;
    &.current {
      color: @color-theme;
    }
  }
}
.list-fixed {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  .fixed-title {
    height: 30px;
    line-height: 30px;
    padding-left: 20px;
    font-size: @font-size-small;
    color: @color-text-l;
    background: @color-highlight-background;
  }
}
</style>